//
//  Person.m
//  消息转发
//
//  Created by tanqilong on 16/8/31.
//  Copyright © 2016年 tanqilong. All rights reserved.
//

#import "Person.h"
#import <objc/runtime.h>
#import "Car.h"

//前两个参数是规定,只有这方才能知道到底是要谁去实现这个方法
void run (id self,SEL _cmd) {
    printf("person run");
}

@implementation Person
//1.找不到run的时候调用此函数然后动态追加一个
+(BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(run)) {
        class_addMethod(self, sel, (IMP)run, "v@:"); //v表示返回值void @表示id类型 :表示SEL类型
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

//2.当resolveInstanceMethod没做处理的时候回调用此函数寻找新的对象处理这个消息
-(id)forwardingTargetForSelector:(SEL)aSelector {
    return [Car new];
}

//3.通过消息签名解决  (如果没有方法实现会返回一个空的消息签名,此时需要手动生成再让forwardInvocation使用)
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    //获取方法名
    NSString * sel = NSStringFromSelector(aSelector);
    if ([sel isEqualToString:@"run"]) {
        //为转发的消息手动生成一个签名
        return [NSMethodSignature signatureWithObjCTypes:"v@:"]; //v表示返回值void @表示id类型 :表示SEL类型
    }
    return [super methodSignatureForSelector:aSelector];
}

-(void)forwardInvocation:(NSInvocation *)anInvocation {
    SEL selec = [anInvocation selector];
    //将消息转发给car来执行
    Car * car = [[Car alloc]init];
    if ([car respondsToSelector:selec]) {
        [anInvocation invokeWithTarget:car];
    }
}

@end
